/**
 * Fenetre.java - Fenêtre principale du jeu
 * 
 * @author BOURGE Denis && BEGORRE Alexandre
 * @version 1.0
 */

package gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import utils.InfoException;
import utils.StringUtils;

import jeu.Partie;

import elements.jetons.Rack;

import elements.plateau.Plateau;

@SuppressWarnings("serial")
public class Fenetre extends JFrame implements ActionListener, MouseListener {

	private JLabel				joueurCourant;
	private JLabel				scoreCourant;
	private JTextField			motJoueur;
	private JLabel				position;
	private int					posX;
	private int					posY;
	private JButton				validerSaisie;
	private JButton				abandonner;
	private JButton				jeterLet;
	private JRadioButton		motVertical;
	private JRadioButton		motHorizontal;
	private Partie				partie;
	private JPanel				vosLettresPane;
	private JPanel				valeursLettresPane;
	private JLabel[]			valeursLettres;

	private static final int	LARGEUR_MAX_MOT		= 15;
	private static final int	LARGEUR_CHAMP_MOT	= 100;
	private static final int	HAUTEUR_CHAMP_MOT	= 25;

	/**
	 * Constructeur de la fenêtre.
	 * 
	 * @param titre
	 *            Titre de la fenêtre
	 * @param largeur
	 *            Largeur de la fenêtre
	 * @param hauteur
	 *            Hauteur de la fenêtre
	 * @throws IOException
	 *             Exception d'Entrée/Sortie
	 */
	public Fenetre(String titre, int largeur, int hauteur) throws IOException {

		/* Paramètres de la fenêtre */
		this.setTitle(titre);
		this.setSize(largeur, hauteur);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(false);

		partie = new Partie("data/dicos/dico_anglais.txt", "Moi", "Lui");

		/* On récupère le ContentPane de la fenêtre */
		Container contenuFenetre = getContentPane();
		contenuFenetre.setLayout(new BorderLayout());

		/* Création du Rack */
		joueurCourant = new JLabel("Joueur " + partie.getJoueurCourant().getNumero() + " - " + partie.getJoueurCourant().getNom());
		scoreCourant = new JLabel("Score: 0");

		JPanel infosJoueurPane = new JPanel();
		infosJoueurPane.setLayout(new BoxLayout(infosJoueurPane, BoxLayout.PAGE_AXIS));
		infosJoueurPane.add(joueurCourant);
		infosJoueurPane.add(scoreCourant);

		vosLettresPane = new JPanel();
		vosLettresPane.setLayout(new BoxLayout(vosLettresPane, BoxLayout.LINE_AXIS));
		for (int i = 0; i < Rack.NOMBRE_LETTRES; i++)
			vosLettresPane.add(partie.getJoueurCourant().prendreRack().getCase(i).getImage());
		vosLettresPane.setPreferredSize(new Dimension(Plateau.TAILLE_LETTRE * Rack.NOMBRE_LETTRES, Plateau.TAILLE_LETTRE));
		vosLettresPane.setMaximumSize(vosLettresPane.getPreferredSize());
		vosLettresPane.setMinimumSize(vosLettresPane.getPreferredSize());

		/* On pioche des lettres */
		partie.getJoueurCourant().prendreRack().piocher(partie.getSac());

		valeursLettres = new JLabel[Rack.NOMBRE_LETTRES];

		valeursLettresPane = new JPanel();
		valeursLettresPane.setLayout(new GridLayout(0, Rack.NOMBRE_LETTRES, 0, Plateau.TAILLE_LETTRE));
		for (int i = 0; i < Rack.NOMBRE_LETTRES; i++) {
			if (partie.getJoueurCourant().prendreRack().getCase(i).getJeton() != null) {
				valeursLettres[i] = new JLabel(String.valueOf(partie.getJoueurCourant().prendreRack().getCase(i).getJeton().getPoints()));
			} else {
				valeursLettres[i] = new JLabel(" ");
			}

			valeursLettresPane.add(valeursLettres[i]);
		}

		valeursLettresPane.setPreferredSize(new Dimension(Plateau.TAILLE_LETTRE * Rack.NOMBRE_LETTRES, Plateau.TAILLE_LETTRE));
		valeursLettresPane.setMinimumSize(valeursLettresPane.getPreferredSize());
		valeursLettresPane.setMaximumSize(valeursLettresPane.getPreferredSize());

		JPanel letValPane = new JPanel();
		letValPane.setLayout(new BoxLayout(letValPane, BoxLayout.PAGE_AXIS));
		letValPane.add(vosLettresPane);
		letValPane.add(valeursLettresPane);

		/* Création du champ pour l'entrée du mot */
		motJoueur = new JTextField(LARGEUR_MAX_MOT);
		motJoueur.setPreferredSize(new Dimension(LARGEUR_CHAMP_MOT, HAUTEUR_CHAMP_MOT));
		motJoueur.setMaximumSize(motJoueur.getPreferredSize());
		motJoueur.setMinimumSize(motJoueur.getPreferredSize());
		position = new JLabel("Position: 7, 7");
		posX = 7;
		posY = 7;

		JPanel posPanel = new JPanel();
		posPanel.setLayout(new BoxLayout(posPanel, BoxLayout.PAGE_AXIS));
		posPanel.add(position);

		/* Création des boutons radio pour le sens du mot */
		motVertical = new JRadioButton("Vertical");
		motVertical.setSelected(true);
		motHorizontal = new JRadioButton("Horizontal");
		ButtonGroup bGroup = new ButtonGroup();
		bGroup.add(motVertical);
		bGroup.add(motHorizontal);
		JPanel bPanel = new JPanel();
		bPanel.setLayout(new BoxLayout(bPanel, BoxLayout.PAGE_AXIS));
		bPanel.add(motVertical);
		bPanel.add(motHorizontal);

		/* Création du bouton de validation */
		validerSaisie = new JButton("Placer mot");
		validerSaisie.addActionListener(this);

		abandonner = new JButton("Passer tour");
		abandonner.addActionListener(this);

		jeterLet = new JButton("Jeter lettres");
		jeterLet.addActionListener(this);

		JPanel boutonsPane = new JPanel();
		boutonsPane.setLayout(new BoxLayout(boutonsPane, BoxLayout.LINE_AXIS));
		boutonsPane.add(abandonner);
		boutonsPane.add(jeterLet);
		boutonsPane.add(validerSaisie);

		JPanel controlesPane = new JPanel();
		controlesPane.setLayout(new BoxLayout(controlesPane, BoxLayout.PAGE_AXIS));
		controlesPane.add(posPanel);
		controlesPane.add(bPanel);

		/* Création des events souris */
		for (int j = 0; j < Plateau.TAILLE_PLATEAU; j++) {
			for (int i = 0; i < Plateau.TAILLE_PLATEAU; i++) {
				partie.getPlateau().getMatrice(i, j).getImage().addMouseListener(this);
			}
		}

		JPanel mainPane = new JPanel();
		mainPane.setLayout(new GridLayout(3, 2, 1, 1));
		mainPane.add(infosJoueurPane);
		mainPane.add(letValPane);
		mainPane.add(motJoueur);
		mainPane.add(controlesPane);

		/* Création du Panel principal où l'on va tout inclure */
		JPanel plateauPane = new JPanel();
		plateauPane.setLayout(new BoxLayout(plateauPane, BoxLayout.PAGE_AXIS));
		plateauPane.add(partie.getPlateau());
		plateauPane.add(mainPane);
		plateauPane.add(boutonsPane);
		/*
		 * plateauPane.add(joueurCourant); plateauPane.add(vosLettresPane);
		 * plateauPane.add(valeursLettresPane); plateauPane.add(monMotLabel);
		 * plateauPane.add(motJoueur); plateauPane.add(controlesPane);
		 * plateauPane.add(boutonsPane);
		 */
		contenuFenetre.add(plateauPane, BorderLayout.CENTER);
	}

	/**
	 * Affiche ou non la fenêtre.
	 * 
	 * @param choix
	 *            Oui/Non
	 */
	public void afficher(boolean choix) {

		setVisible(choix);
	}

	/**
	 * Mettre à jour la fenêtre
	 */
	public void mettreAJour() {

		vosLettresPane.removeAll();
		valeursLettresPane.removeAll();

		partie.getJoueurCourant().prendreRack().piocher(partie.getSac());

		for (int i = 0; i < Rack.NOMBRE_LETTRES; i++) {
			vosLettresPane.add(partie.getJoueurCourant().prendreRack().getCase(i).getImage());

			if (partie.getJoueurCourant().prendreRack().getCase(i).getJeton() != null) {
				valeursLettres[i].setText(String.valueOf(partie.getJoueurCourant().prendreRack().getCase(i).getJeton().getPoints()));
			} else {
				valeursLettres[i].setText(" ");
			}

			valeursLettresPane.add(valeursLettres[i]);
		}

		joueurCourant.setText("Joueur " + partie.getJoueurCourant().getNumero() + " - " + partie.getJoueurCourant().getNom());
		scoreCourant.setText("Score: " + partie.getJoueurCourant().getScore());

		motJoueur.setText("");
	}

	/**
	 * Fonction principale.
	 * 
	 * @param args
	 *            Arguments en ligne de commande
	 */
	public static void main(String[] args) {

		Fenetre fen = null;
		try {
			fen = new Fenetre("MScrabble", 500, 740);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		fen.afficher(true);
	}

	/**
	 * Traitement des actions sur la fenêtre
	 */
	public void actionPerformed(ActionEvent ae) {

		if (ae.getSource() == (Object) validerSaisie) {
			if (!motJoueur.getText().equals("")) {
				try {
					partie.saisieMot(this, posX, posY, motHorizontal.isSelected(), motJoueur.getText());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				JOptionPane.showMessageDialog(this, "Le mot est vide !", "Gné", JOptionPane.ERROR_MESSAGE);
			}
		} else if (ae.getSource() == (Object) abandonner) {
			if (partie.getAutreJoueur().aAbandonne()) {
				partie.partieTerminee(this);
			} else {
				partie.getJoueurCourant().abandon(true);
				JOptionPane.showMessageDialog(this, partie.getJoueurCourant().getNom() + " a passé son tour.\nSi vous faites de même, la partie est finie.", "Abandon ?", JOptionPane.INFORMATION_MESSAGE);

				partie.permuterJoueur();
				this.mettreAJour();
				this.repaint();
			}
		} else if (ae.getSource() == (Object) jeterLet) {
			try {
				if (motJoueur.getText().equals("")) partie.getJoueurCourant().prendreRack().jeterLettres("", partie.getSac());
				else
					partie.getJoueurCourant().prendreRack().jeterLettres(StringUtils.normalizeWord(motJoueur.getText()), partie.getSac());

				JOptionPane.showMessageDialog(this, "Vos jetons seront changés.\n" + partie.getAutreJoueur().getNom() + ", à vous !", "OK !", JOptionPane.INFORMATION_MESSAGE);
				partie.permuterJoueur();
				this.mettreAJour();
				this.repaint();

			} catch (InfoException e) {
				// TODO Auto-generated catch block
				JOptionPane.showMessageDialog(this, "Erreur: " + e.getMessage(), "Exception levée", JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	/**
	 * Traitement des clic de souris
	 */
	public void mouseClicked(MouseEvent me) {

		for (int j = 0; j < Plateau.TAILLE_PLATEAU; j++) {
			for (int i = 0; i < Plateau.TAILLE_PLATEAU; i++) {
				if (me.getSource() == (Object) partie.getPlateau().getMatrice(i, j).getImage()) {
					posX = i;
					posY = j;

					position.setText("Position: " + posX + ", " + posY);
				}

			}
		}
	}

	public void mouseReleased(MouseEvent me) {

	}

	public void mouseEntered(MouseEvent me) {

	}

	public void mousePressed(MouseEvent me) {

	}

	public void mouseExited(MouseEvent me) {

	}
}